/**
 * 线程池模版类(小型)
 * @author: sundx
 * @date: 2020-06-06 22:12:04
 * @Last Modified by: sundx
 * @Last Modified time: 2020-06-07 01:57:10
 */
#ifndef __THREADPOLL__
#define __THREADPOLL__

#include "locker.h"
#include <list>
#define MAX_EVENT_NUMBER 10000

template <typename T> class threadpoll {
public:
  threadpoll(int thread_number = 8, int max_requests = MAX_EVENT_NUMBER);
  ~threadpoll();
  bool append(T *request);

private:
  /*工作线程运行的函数，它不断从工作队列中取出任务并执行之，静态函数，实际调用成员函数run()*/
  static void *worker(void *arg);
  void run();

private:
  int m_thread_number;  //线程池中的线程数
  int m_max_requests;   //请求队列中允许的最大请求数
  pthread_t *m_threads; //描述线程池的数组，其大小为m_thread_number
  std::list<T *> m_workqueue; //请求队列
  mutexLock m_queuelocker;    //保护请求队列的互斥锁
  sem m_queuestat;            //是否有任务需要处理
  bool m_stop;                //是否结束线程
};

template <typename T>
threadpoll<T>::threadpoll(int thread_number, int max_requests)
    : m_thread_number(thread_number), m_max_requests(max_requests),
      m_stop(false), m_threads(nullptr) {
  if ((thread_number <= 0) || (max_requests <= 0)) {
    printError("thread_number,max_requests error...");
  }
  m_threads = new pthread_t[m_max_requests]; //创建线程id数组；
  if (!m_threads)
    printError("m_threads error...");
  for (int i = 0; i < thread_number; ++i) {
    if (pthread_create(m_threads + i, nullptr, worker, this) != 0) { //创建线程
      delete[] m_threads;
      printError("pthread_create error...");
    }
    if (pthread_detach(m_threads[i]) != 0) { //分离
      delete[] m_threads;
      printError("pthread_detach error...");
    }
  }
}

template <typename T> void *threadpoll<T>::worker(void *arg) {
  threadpoll *pool = (threadpoll *)arg; // arg传入 this指针；
  pool->run();
  return pool;
}

template <typename T> void threadpoll<T>::run() { //线程实际调用的成员函数
  while (!m_stop) { //等待条件变量，加锁，取出任务，解锁，执行任务；
    m_queuestat.wait();
    m_queuelocker.lock();
    if (m_workqueue.empty()) {
      m_queuelocker.unlock();
      continue;
    }
    T *request = m_workqueue.front();
    m_workqueue.pop_front();
    m_queuelocker.unlock();
    if (!request)
      continue;
    request->process(); //调用 T类 中的 process方法；执行操作
  }
}

template <typename T> bool threadpoll<T>::append(T *request) {
  m_queuelocker.lock();                      //先加锁
  if (m_workqueue.size() > m_max_requests) { //满了
    m_queuelocker.unlock();
    return false;
  }
  m_workqueue.push_back(request);
  m_queuelocker.unlock();
  m_queuestat.post(); //通知
  return true;
}

template <typename T> threadpoll<T>::~threadpoll() { delete[] m_threads; }

#endif